package com.zylix.simon.checking.notes;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.app.Activity;
import android.app.ListActivity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.Layout;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.android.notepad.R;
import com.example.android.notepad.NotePad.NoteColumns;

public class CheckNoteActivity  extends Activity {
	private static final String TAG = "CheckNoteActivity";
	 /**
     * Standard projection for the interesting columns of a normal note.
     */
    private static final String[] PROJECTION = new String[] {
        NoteColumns._ID, // 0
        NoteColumns.NOTE, // 1
        NoteColumns.NOTE_TYPE, //2
        NoteColumns.TITLE, // 3
    };

    private static final int COLUMN_INDEX_NOTE = 1;
    private static final int COLUMN_INDEX_NOTE_TYPE = 2;
    private static final int COLUMN_INDEX_TITLE = 3;
    
    
    // This is our state data that is stored when freezing.
    private static final String ORIGINAL_CONTENT = "origContent";

    // The different distinct states the activity can be run in.
    private static final int STATE_EDIT = 0;
    private static final int STATE_INSERT = 1;

    private int mState;
    private Uri mUri;
    private Cursor mCursor;
    private EditText mText;
    private String mOriginalContent;
    
    
    /** Called when the activity is first created. */
	private ListView myListView;
	private MyAdapter myadapter;
	private Button item_btn;
    private Button.OnClickListener listener_item = null;
    private List<CheckItemData> checkitem_list;
    private EditText input;
    private XMLAdapter xmladapter;
    private int item_counter = 0;
    private String title_fromDB;
    private String full_path_fromDB;
    private boolean item_editable = false;
    private String original_title;
    private int original_list_length;
    
    protected static final int MyListView_camera = 0, MyListView_album = 1, MyListView_map = 2;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.note_checker);
        prepareDataBase(savedInstanceState);
        prepareViews();
        prepareModels();

        myListView.setAdapter(myadapter);
        myListView.setOnItemClickListener(new ListView.OnItemClickListener()
	    {
			@Override
			public void onItemClick(AdapterView<?> parent, View arg1, int position,
					long id) {
				CheckBox cbx = (CheckBox)arg1.findViewById(R.id.MyAdapter_CheckBox_checkBox);
				TextView title = (TextView)arg1.findViewById(R.id.MyAdapter_TextView_title);
				data_dump();
				CheckItemData cid = (CheckItemData)checkitem_list.get(position);
				Log.i(TAG, "myListView.setOnItemClickListener" + cid.getItemId());
				if(cbx.isChecked()){
					cbx.setChecked(false);
					input.setText("");
					item_editable = false;
					int itid = checkitem_list.get(position).getItemId();
					xmladapter.modifyCheckStatusbyID(checkitem_list.get(position).getItemId(), false);
				}else{
					cbx.setChecked(true);
					input.setText(title.getText().toString());
					item_editable =true;
					int itid = ((CheckItemData)checkitem_list.get(position)).getItemId();
					xmladapter.modifyCheckStatusbyID(itid, true);
				}
			}
	    });
        registerForContextMenu(myListView);
    }
    
    public void onCreateContextMenu(ContextMenu menu, View v,
    		ContextMenuInfo menuInfo) {
    	if (v.getId()==R.id.list) {
    	    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
    		menu.setHeaderTitle(checkitem_list.get(info.position).getItemTitle());
    		String[] menuItems = getResources().getStringArray(R.array.option); 
    		for (int i = 0; i<menuItems.length; i++) {
    			menu.add(Menu.NONE, i, i, menuItems[i]);
			}
    	}
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	this.getMenuInflater().inflate(R.menu.check_menu, menu);
    	return true;
    }
    
    private int getRandom(int min,int max){
        long seed = System.currentTimeMillis();
        Random r = new Random(); 
        r.setSeed(seed);        
        return (min + r.nextInt(max-min+1));
    }
    
    @Override
	public boolean onOptionsItemSelected(MenuItem item) {
    	Log.i(TAG, "onOptionItemSelected");

    	switch(item.getItemId()){
		case R.id.item_save:
			Toast.makeText(this, "Check note saved", Toast.LENGTH_LONG).show();
			saveNote();
			finish();
			break;
		case R.id.item_discard:
			Toast.makeText(this, "Discard item selected", Toast.LENGTH_LONG).show();
			cancelNote();
			finish();
			break;    		
    	}
		return super.onOptionsItemSelected(item);
	}

	@Override
    public boolean onContextItemSelected(MenuItem item) {
	    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
	    int menuItemIndex = item.getItemId();
		String[] menuItems = getResources().getStringArray(R.array.option);
		String menuItemName = menuItems[menuItemIndex];
	    String listItemName = checkitem_list.get(info.position).getItemTitle();
	    Toast.makeText(CheckNoteActivity.this, "Selected "+menuItemName+" for item "+listItemName, Toast.LENGTH_SHORT).show();
	    Log.i(TAG,"onContextItemSelected : info.position" + info.position);
	    checkitem_list.remove(info.position);
	    xmladapter.deleteNode(info.position);
	    myadapter.setList(checkitem_list);
	    myadapter.notifyDataSetChanged();
    	return true;
    }
	
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		Log.i(TAG, "CheckNoteActivity::onPause() called");
		super.onPause();
        if (!isCheckNoteEmpty()) {
            setResult(RESULT_CANCELED);
            deleteNote();
        } else {
            saveNote();
        }
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
	}
	
	private boolean isCheckNoteEmpty(){
		boolean ret = false;
		EditText et = (EditText)this.findViewById(R.id.titleeditor);
		if(!et.getText().equals("") || !checkitem_list.isEmpty())
			ret = true;
		return ret;
	}
    
	private boolean isCheckNoteChanged(){
		boolean ret = false;
		EditText et = (EditText)this.findViewById(R.id.titleeditor);
		if(mState == STATE_INSERT){
			if(!et.getText().equals("") || !checkitem_list.isEmpty())
				ret = true;
		}else if(mState == STATE_EDIT){
			if(!et.getTag().equals(original_title) || checkitem_list.size() != this.original_list_length)
				ret = true;
		}else{
			Log.i(TAG, "Error CheckNote status");
		}
		return ret;
	}
	

	
	private void prepareDataBase(Bundle savedInstanceState){
        
		final Intent intent = getIntent();
        // Do some setup based on the action being performed.
        final String action = intent.getAction();
        if (Intent.ACTION_INSERT.equals(action)) {
            // Requested to insert: set that state, and create a new entry
            // in the container.
            mState = STATE_INSERT;
            mUri = getContentResolver().insert(intent.getData(), null);

            // If we were unable to create a new note, then just finish
            // this activity.  A RESULT_CANCELED will be sent back to the
            // original activity if they requested a result.
            if (mUri == null) {
                Log.e(TAG, "Failed to insert new note into " + getIntent().getData());
                finish();
                return;
            }

            // The new entry was created, so assume all will end well and
            // set the result to be returned.
            setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));

        } else if(Intent.ACTION_EDIT.equals(action)){
        	mState = STATE_EDIT;
        	mUri = intent.getData();        	
        }else{
            // Whoops, unknown action!  Bail.
            Log.e(TAG, "Unknown action, exiting");
            finish();
            return;
        }
        
        // Get the note!
        mCursor = managedQuery(mUri, PROJECTION, null, null, null);
        // If an instance of this activity had previously stopped, we can
        // get the original text it started with.
        if (savedInstanceState != null) {
            mOriginalContent = savedInstanceState.getString(ORIGINAL_CONTENT);
        }
	}
	
	private void prepareViews()
	{
        myListView = (ListView)this.findViewById(R.id.list);
        myListView.setEmptyView(this.findViewById(R.id.empty));
        input = (EditText)this.findViewById(R.id.itemeditor);
    	item_btn = (Button)this.findViewById(R.id.itemaddbutton);
    	final EditText it = (EditText)this.findViewById(R.id.itemeditor);
    	listener_item = new Button.OnClickListener() {
    	    @Override
    	    public void onClick(View v)
    	    {   
    	    	if(it.getText().toString().equals(""))
    	    		return;
    	    	
    	    	CheckItemData cid = new CheckItemData(item_counter, input.getText().toString(), false);
    	    	cid.setItemId(checkitem_list.size());
    	    	checkitem_list.add(cid);
    	        myadapter.setList(checkitem_list);
    	        xmladapter.appendNode(cid.getItemId(), input.getText().toString(), false);
    	        myadapter.notifyDataSetChanged();
    	        input.setText("");
    	        item_editable = false; 
    	        item_counter++;
    	    }
    	};
    	item_btn.setOnClickListener(listener_item);    	
    }
    
	private void prepareModels(){
		if(mState == STATE_INSERT){
        checkitem_list = new ArrayList<CheckItemData>();
        myadapter = new MyAdapter(this, checkitem_list);
        initialXML();
		}else if(mState == STATE_EDIT ){
	        if (mCursor != null) {
	            mCursor.requery();
	            mCursor.moveToFirst();
	            this.title_fromDB = mCursor.getString(COLUMN_INDEX_TITLE);
	            this.full_path_fromDB = mCursor.getString(COLUMN_INDEX_NOTE);
	            //Log.i(TAG,title_fromDB);
	            //Log.i(TAG, full_path_fromDB);
	            xmladapter = new XMLAdapter(this.full_path_fromDB);
	            checkitem_list = xmladapter.getXMLData();
	            myadapter = new MyAdapter(this,checkitem_list);
	            TextView tv = (TextView)this.findViewById(R.id.titleeditor);
	            tv.setText(title_fromDB);
	            //Keep these data as original in order to identify changing.
	            this.original_title = title_fromDB;
	            this.original_list_length = checkitem_list.size();
	        }
		}
	}
	
    private void initialXML(){
    	xmladapter = new XMLAdapter();
    }
    
    private void updateContenProvider(String abs_filename, String filename){

        //-------Update dtatbase-------
        //-------The file name will be saved into NOTE column-------
    	String title = filename.substring(0, filename.lastIndexOf("."));
    	Log.i(TAG, "Make sure the title is "+title);
        if (mCursor != null) {
            // Get out updates into the provider.
            ContentValues values = new ContentValues();

            //Add the note type as the text note
            values.put(NoteColumns.NOTE_TYPE, "check");
            
            // Bump the modification time to now.
            values.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());

            int length = abs_filename.length();
            // If we are creating a new note, then we want to also create
            // an initial title for it.
            if (mState == STATE_INSERT) {
            	Log.i(TAG, new Integer(length).toString());
                if (length == 0) {
                    Toast.makeText(this, R.string.nothing_to_save, Toast.LENGTH_SHORT).show();
                    return;
                }
                values.put(NoteColumns.TITLE, title);
            }

            // Write our text back into the provider.
            values.put(NoteColumns.NOTE, abs_filename +"/"+ filename);

            // Commit all of our changes to persistent storage. When the update completes
            // the content provider will notify the cursor of the change, which will
            // cause the UI to be updated.
            try {
                getContentResolver().update(mUri, values, null, null);
            } catch (NullPointerException e) {
                Log.e(TAG, e.getMessage());
            }
            
        }
    }
    
	private String getFileName(){
		String FileName;
    	EditText et = (EditText)this.findViewById(R.id.titleeditor);
    	if(et.getText().toString().equals("")){
    		SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd"); 
    		String date = sDateFormat.format(new java.util.Date()); 
    		FileName = "CheckNote-" + date + new Integer(getRandom(100,10000)).toString() + ".xml";
    	}else{
    		FileName = et.getText().toString() + ".xml";
    	}
    	return FileName;
	}
    
    private void deleteNote()
    {
    	if (mCursor != null) {
        mCursor.close();
        mCursor = null;
        getContentResolver().delete(mUri, null, null);
    	}    	
    }
    
    private final void cancelNote() {
        if (mCursor != null)
        	deleteNote();
        setResult(RESULT_CANCELED);
        finish();
    }
    
    private final void saveNote(){
    	String FileName = getFileName();
		updateContenProvider(xmladapter.saveXml(FileName), FileName);
    }
    
    //debug only
    private void data_dump(){
    	if(checkitem_list != null){
    		Log.i(TAG, "Item List Length is " + checkitem_list.size());
    		for(int i=0; i<checkitem_list.size(); i++)
    			 checkitem_list.get(i).dump_data();
    	}else{
    		Log.i(TAG, "Error NULL data dumping!");
    	}
    }
}
